import { updateQueue } from "./Component"

/**
 * 给DOM元素添加事件处理函数
 * @param {*} dom 要添加事件的DOM元素
 * @param {*} eventType 事件类型
 * @param {*} handler 事件处理函数
 */
export function addEvent(dom,eventType,handler){
    // console.log(dom,eventType,handler)
    // 判断dom上有没有store属性,如果有直接返回，如果没，则赋值为空对象然后返回
    let store = dom.store || (dom.store = {})
    // 向store中存放属性和值，属性是事件类型onclick 值是一个事件函数
    store[eventType.toLowerCase()] = handler
    const eventName = eventType.slice(2).toLowerCase()
    if(!document.binded){
        // 如果你想要监听捕获和冒泡的凉饿阶段onClick
        document.addEventListener(eventName, event => {
            dispatchEvent(event, true);
        }, true);
        document.addEventListener(eventName, event => {
            dispatchEvent(event, false);
        }, false);
        document.binded = true
        // document[eventType.toLowerCase()] = dispatchEvent
    }
}
function dispatchEvent(event,isCapture){
    // 为什么要做事件委托 为什么要把子DOM事件全部委托给父类
    // 1.为了减少绑定，提高性能 2.统一进行事件实现合成事件
    // target 事件源 type事件名称 click
    const {target,type} = event
    let eventType = `on${type}`//onclick
    let eventTypeCapture = `on${type}capture` //onClick
    let syntheticEvent = createSyntheticEvent(event)
    updateQueue.isBatchingUpdate = true
    // 为了跟源码一样，我们需要自己手工再模拟捕获和冒泡的全过程
    // 我们需要先记录一栈结构
    let targetStack = []
    let currentTarget = target
    while(currentTarget){
        targetStack.push(currentTarget)
        currentTarget = currentTarget.parentNode
    }
    if(isCapture){
            // 处理捕获阶段
        for(let i=targetStack.length-1;i>=0;i--){
            const currentTarget = targetStack[i]
            let {store} = currentTarget
            let handler = store&&store[eventTypeCapture]
            handler&&handler(syntheticEvent)
        }
    }else{
        // 处理冒泡阶段
        for(let i=0;i<targetStack.length;i++){
            const currentTarget = targetStack[i]
            let {store} = currentTarget
            let handler = store&&store[eventType]
            handler&&handler(syntheticEvent)
            if (syntheticEvent.isPropagationStopped) {
                break;
            }
        }
    }



    // // 第一步先获取当前的事件源document
    // let currentTarget = event.currentTarget
    // while(currentTarget){
    //     let {store} = currentTarget
    //     let handler = store&&store[eventTypeCapture]
    //     handler&&handler(syntheticEvent)
    // }
    // // 在执行事件函数之前把isBatchingUpdate设置为true，也就是把批量更新打开
    // // 现在实现批量更新
    updateQueue.batchUpdate()
}

/**
 * 根据原生事件对象创建合成事件
 * 1.为了实现兼容性处理
 * @param {*} nativeEvent 
 */
function createSyntheticEvent(nativeEvent){
    let syntheticEvent = {}
    for(let key in nativeEvent){
        let value = nativeEvent[key]
        if(typeof value === 'function') value = value.bind(nativeEvent)
        syntheticEvent[key] = value
    }
    syntheticEvent.nativeEvent = nativeEvent
    // 是否已经阻止了默认事件
    syntheticEvent.isDefaultPrevented = false
    syntheticEvent.preventDefault = preventDefault
    syntheticEvent.isPropagationStopped = false
    syntheticEvent.stopPropagation = stopPropagation
    return syntheticEvent;
}

function preventDefault(){
    this.isDefaultPrevented = true
    const nativeEvent = this.nativeEvent
    if(nativeEvent.preventDefault){
        nativeEvent.preventDefault()
    }else{//IE
        nativeEvent.returnValue = false
    }
}

function stopPropagation(){
    this.isPropagationStopped = true
    const nativeEvent = this.nativeEvent
    if(nativeEvent.stopPropagation){
        nativeEvent.stopPropagation()
    }else{//IE
        nativeEvent.cancelBubble = true
    }
}